import type { Router, RouteRecordRaw } from 'vue-router'
import { useUserStoreWithOut } from '@/store/modules/user'

import { resetRouter } from '@/router'
import { ROUTER_NAME, WHITE_ROUTER_LIST } from '@/constant'
import { fetchUserInfo } from '@/apis/sys/user'
import { asyncRoutes } from '@/router/routes'
import { resetRoutePath } from "@/router/util";
import { LayoutMenu } from "@/layouts/hooks/getLayoutMenu";

import dpaHiddenRouter from '@/router/routes/modules/dpaHiddenRouter'
import hiddenPageRouter from '@/router/routes/modules/hiddenPageRouter'
import hiddenRefRouter from '@/router/routes/modules/hiddenRefRouter'
import redirectBase from '@/router/routes/modules/redirectBase'
import additionPage from '@/router/routes/modules/additionPage'


const HIDDEN_ROUTER_MAP = [
    ...(dpaHiddenRouter.children ?? []),
    ...(hiddenPageRouter.children ?? []),
    ...(hiddenRefRouter.children ?? []),
    ...(redirectBase.children ?? []),
    ...(additionPage.children ?? []),
].map(item => {
    return item.name;
})

const whitePathList: String[] = [ROUTER_NAME.PAGE_LOGIN, ROUTER_NAME.AUTH_LOGIN]

export function createPermissionGuard(router: Router) {
    const layoutMenu = new LayoutMenu();
    // 判断是否是子应用
    const microAppData = window.microApp?.getData() ?? window.eventCenterForViteApp?.getData()

    // 根据打开的域名重置route
    resetRoutePath(asyncRoutes);

    const userStore = useUserStoreWithOut()
    // 作为子应用使用  这里重要！作为子路由时获取基座的登录信息
    if (microAppData && !userStore.getName) {
        const { userInfo } = microAppData
        const { userItem } = userInfo
        userStore.setUserInfo(userItem)
        userStore.buildPermissionInfo(userInfo.resourcesItems)
        // 构建路由信息
        // 基于用户权限信息构建路由
        resetRouter()
        asyncRoutes.forEach((route: any) => {
            router.addRoute(route as unknown as RouteRecordRaw)
        })
    } else {
      resetRouter()
      asyncRoutes.forEach((route: any) => {
        router.addRoute(route as unknown as RouteRecordRaw)
      })
    }
    router.beforeEach(async (to, from, next) => {
        // 作为子应用被调用 作为子路由时权限放开
        if (microAppData) {
            next()
            return
        }
        const token = userStore.getToken
        //
        // Whitelist can be directly entered
        if (whitePathList.includes(to.name as string)) {
            if (to.name === ROUTER_NAME.PAGE_LOGIN && token && token.length > 0) {
                // 清除Token信息及用户信息
                userStore.logout()
                // 清除路由信息
                resetRouter()
                next()
            }
            next()
            return
        }
        if (!token) {
            if (to.meta.ignoreAuth) {
                next()
                return
            }
            // 清除Token信息及用户信息
            userStore.logout()
            // 重置路由
            resetRouter()

            // redirect login page
            const redirectData: { name: string; replace: boolean; params: any; query?: Record<string, string> } = {
                name: ROUTER_NAME.PAGE_LOGIN,
                replace: true,
                params: to.params,
            }
            if (to.path) {
                redirectData.query = {
                    ...redirectData.query,
                    redirect: to.path
                }
            }
            next(redirectData)
            return
        }
        if (!userStore.getName) {
            // 调用API获取信息
            try {
                const userInfo = await fetchUserInfo()
                if (userInfo) {
                    const { userItem } = userInfo
                    userStore.setUserInfo(userItem)
                    userStore.buildPermissionInfo(userInfo.resourcesItems)
                    // 构建路由信息
                    // 基于用户权限信息构建路由
                    resetRouter()
                    asyncRoutes.forEach(route => {
                        router.addRoute(route as unknown as RouteRecordRaw)
                    })
                    // 获取用户信息后，如果目标页是403页，跳到首页
                    if (to.name === ROUTER_NAME.PAGE_NO_ACCESS) {
                        next({ name: ROUTER_NAME.PAGE_ROOT, params: to.params, replace: true })
                    }
                }
            } catch (error) {
                // 获取用户信息出错，跳转到登录页面
                if (to.meta.ignoreAuth) {
                    next()
                    return
                }
                // 清除Token信息及用户信息
                userStore.logout()
                // 重置路由
                resetRouter()

                // redirect login page
                const redirectData: { name: string; replace: boolean; query?: Record<string, string> } = {
                    name: ROUTER_NAME.PAGE_LOGIN,
                    params: to.params,
                    replace: true
                }
                if (to.path) {
                    redirectData.query = {
                        ...redirectData.query,
                        redirect: to.path
                    }
                }
                next(redirectData)
                return
            }
        }
        // 首次进入都会进入404页（·.·）
        if (to.name === ROUTER_NAME.PAGE_NOT_FOUND) {
            const allRoutes = router.getRoutes()
            // 判断如果当前路径确实在所有在路由表里，继续向下走
            if (allRoutes.some(item => {
                // 如果是根目录，校验是否完全一致
                if (item.path === import.meta.env.VITE_PUBLIC_PATH + '/') {
                    return item.path === to.path
                }
                // 排除只有根目录的情况
                if (item.path && item.path !== import.meta.env.VITE_PUBLIC_PATH + '/:pathMatch(.*)*') {
                    return new RegExp(item.path.replace('(.*)*', '').replace(/:(\w+)/g, '.+'), 'g').test(to.path)
                } else {
                    return false
                }
            })) {
                next({ path: to.fullPath, replace: true, query: to.query })
            } else {
                next()
            }
            return
        } else if (WHITE_ROUTER_LIST.includes(to.name as string) || (HIDDEN_ROUTER_MAP && HIDDEN_ROUTER_MAP.includes(to.name as string))) {
            // 如果使用的micro-app，暂时不判断权限
            next()
            return
        } else {
            // 判断路由权限
            if (!to?.meta?.code) {
                next()
                return
            }
            const { fullPath } = to;
            const menuCode = layoutMenu.getPathByCode(decodeURIComponent(fullPath));
            const menuCodeUnDecode = layoutMenu.getPathByCode(fullPath);
            const permissionCodeMap = userStore.getPermissionMap
            if (permissionCodeMap?.includes(to.meta.code)  || (menuCode && permissionCodeMap?.includes(menuCode)) || (menuCodeUnDecode && permissionCodeMap?.includes(menuCodeUnDecode))) {
                next()
                return
            } else {
                next({ name: ROUTER_NAME.PAGE_NO_ACCESS, params: to.params, replace: true })
                return
            }
        }
    })
}
